<?php

declare(strict_types=1);

namespace Tool\Command;

use Exception;
use Marx\Console\Color;
use Marx\Console\Command\AbstractCommand;

/**
 * host维护.
 */
class HostCommand extends AbstractCommand
{
    private string $path;

    public function __construct()
    {
        $this->setName('host');
        $this->setDesc('update win host,e.g. tool host add "www.host.com",e.g. tool host delete "127.0.0.1 www.host.com"');
        $this->addArgument('command', true, 'command:all list add delete', 'list');
        $this->addArgument('host', false, 'the host');
        $this->path = $_SERVER['SystemRoot'].'/System32/drivers/etc/hosts';
    }

    public function execute(): void
    {
        $command = $this->input->getArgument('command');
        if (!in_array($command, ['all', 'list', 'add', 'delete'], true)) {
            $command = 'all';
        }

        $this->{$command}();
    }

    private function all(): void
    {
        $this->output->write($this->getContent());
    }

    private function list($highlightHost = null): void
    {
        foreach ($this->getContentList() as $host) {
            $host = $highlightHost === $host ? Color::green($host) : $host;
            $this->output->write($host);
        }
    }

    private function add(): void
    {
        $host = $this->getHost();
        $content = trim($this->getContent())."\n".$host."\n";
        $this->setContent($content);
        $this->list($host);
    }

    private function delete(): void
    {
        $host = $this->getHost();
        $content = str_replace("\n".$host, '', $this->getContent());
        $this->setContent($content);
        $this->list();
    }

    private function getContentList(): array
    {
        $content = $this->getContent();
        preg_match_all('/\n(\d{1,3}(?:[.]\d{1,3}){3} [^\n]+)/', $content, $matches);

        return $matches[1];
    }

    private function getContent(): string
    {
        return file_get_contents($this->path);
    }

    private function getHost(): string
    {
        $host = $this->input->getArgument('host');
        if (!$host) {
            throw new Exception('please input host');
        }

        if (false === strpos($host, ' ')) {
            $host = '127.0.0.1 '.$host;
        }

        return $host;
    }

    private function setContent(string $content): void
    {
        file_put_contents($this->path, $content);
    }
}
